package com.gxa.goods.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.gxa.goods.mapper.SkuMapper;
import com.gxa.goods.service.SkuService;
import com.gxa.luckin.core.exception.BusinessException;
import com.gxa.luckin.core.exception.MessageCode;
import com.gxa.luckin.core.pojo.Sku;
import com.gxa.luckin.core.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service("skuService")
@Transactional(rollbackFor = Throwable.class)
public class SkuServiceImpl implements SkuService {

    @Resource
    private SkuMapper skuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

//设置商品sku的redis前缀
    private static final String SKU_GOOD="sku:";

    // 指定过期时间常量
    private static final Integer SKU_CACHE=2;
    /**
     * 查询全部列表
     * @return
     */
    @Override
    public List<Sku> findAll() {
        return skuMapper.selectAll();
//        return skuMapper.findAll();
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     */
    @Override
    public Sku findById(String id) throws BusinessException {
        //redisTemplate来查看sku
        BoundValueOperations<String,Object> skuOps = redisTemplate.boundValueOps(SKU_GOOD + id);
        //先从缓存中找,有就返回
        Object skuObject= skuOps.get();
        //判断是否为空sku
        boolean empty = StringUtils.isEmpty(skuObject);
        //如果没有,就从数据库中找,放入缓存
        if(empty){
        Sku sku=new Sku();
        //查询存在的sku的id
        sku.setId(id);

        Sku selectSku = skuMapper.selectOne(sku);
            //  当sku在数据库不存在,就抛出业务异常
            if (selectSku==null){
                throw new BusinessException(MessageCode.BANNER_INDEX_QUANTITY);
            }else {
                //找到做缓存,转换为json格式
                //返回查询到的selectSku
                String objectToJson = JsonUtils.objectToJson(selectSku);
                skuOps.set(objectToJson,SKU_CACHE,TimeUnit.HOURS);
                return selectSku;
            }
        }
        else {
            Sku sku = JsonUtils.jsonToObject(skuOps.toString(), Sku.class);
            return sku;
        }
    }

    /**
     * 增加
     * @param sku
     */
    @Override
    public void add(Sku sku){
        //添加sku

        skuMapper.insert(sku);
    }


    /**
     * 修改
     * @param sku
     */
    @Override
    public void update(Sku sku){
       skuMapper.updateByPrimaryKey(sku);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id){
        skuMapper.deleteByPrimaryKey(id);
    }


    /**
     * 条件查询
     * @param searchMap
     * @return
     */
    @Override
    public List<Sku> findList(Map<String, Object> searchMap){
        Example example = createExample(searchMap);
        return skuMapper.selectByExample(example);
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Sku> findPage(int page, int size){
        PageHelper.startPage(page,size);
        return (Page<Sku>)skuMapper.selectAll();
    }

    /**
     * 条件+分页查询
     * @param searchMap 查询条件
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Override
    public Page<Sku> findPage(Map<String,Object> searchMap, int page, int size){
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        return (Page<Sku>)skuMapper.selectByExample(example);
    }


    /**
     * 购物车操作涉及一个购物车表
     * @param username
     */

    @Override
    @Transactional
    public void decrCount(String username) {
        //1.获取购物车中的数据
//        List<OrderItem> orderItemList = redisTemplate.boundHashOps("cart_" + username).values();

        //2.循环扣减库存并增加销量
//        for (OrderItem orderItem : orderItemList) {
//            int count = skuMapper.decrCount(orderItem);
//            if (count <= 0){
//                throw new RuntimeException("库存不足,请重试");
//            }
//        }
    }

    @Override
    @Transactional
    public void resumeStockNum(String skuId, Integer num) {
        skuMapper.resumeStockNum(skuId, num);
    }

//    @Override
//    public List<Sku> selectAllByPosition(String postion) {
//    Sku sku=new Sku();
//    sku.setPosition(postion);
//        org.springframework.data.domain.Example<Sku> of = org.springframework.data.domain.Example.of(sku);
//        Sort id=Sort.by(Sort.Direction.ASC,"id");
//        return skuMapper.findAll(of,id);
//    }

    /**
     * 构建查询对象
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Sku.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 商品id
            if(searchMap.get("id")!=null && !"".equals(searchMap.get("id"))){
                criteria.andEqualTo("id", searchMap.get("id"));
           	}
            // 商品条码
            if(searchMap.get("sn")!=null && !"".equals(searchMap.get("sn"))){
                criteria.andEqualTo("sn",searchMap.get("sn"));
           	}
            // SKU名称
            if(searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
           	}
            // 商品图片
            if(searchMap.get("image")!=null && !"".equals(searchMap.get("image"))){
                criteria.andLike("image","%"+searchMap.get("image")+"%");
           	}
            // 商品图片列表
            if(searchMap.get("images")!=null && !"".equals(searchMap.get("images"))){
                criteria.andLike("images","%"+searchMap.get("images")+"%");
           	}
            // SPUID
            if(searchMap.get("spuId")!=null && !"".equals(searchMap.get("spuId"))){
                criteria.andEqualTo("spuId",searchMap.get("spuId"));
           	}
            // 类目名称
            if(searchMap.get("categoryName")!=null && !"".equals(searchMap.get("categoryName"))){
                criteria.andLike("categoryName","%"+searchMap.get("categoryName")+"%");
           	}
            // 品牌名称
            if(searchMap.get("brandName")!=null && !"".equals(searchMap.get("brandName"))){
                criteria.andLike("brandName","%"+searchMap.get("brandName")+"%");
           	}
            // 规格
            if(searchMap.get("spec")!=null && !"".equals(searchMap.get("spec"))){
                criteria.andLike("spec","%"+searchMap.get("spec")+"%");
           	}
            // 商品状态 1-正常，2-下架，3-删除
            if(searchMap.get("status")!=null && !"".equals(searchMap.get("status"))){
                criteria.andEqualTo("status", searchMap.get("status"));
           	}

            // 价格（分）
            if(searchMap.get("price")!=null ){
                criteria.andEqualTo("price",searchMap.get("price"));
            }
            // 库存数量
            if(searchMap.get("num")!=null ){
                criteria.andEqualTo("num",searchMap.get("num"));
            }
            // 库存预警数量
            if(searchMap.get("alertNum")!=null ){
                criteria.andEqualTo("alertNum",searchMap.get("alertNum"));
            }
            // 重量（克）
            if(searchMap.get("weight")!=null ){
                criteria.andEqualTo("weight",searchMap.get("weight"));
            }
            // 类目ID
            if(searchMap.get("categoryId")!=null ){
                criteria.andEqualTo("categoryId",searchMap.get("categoryId"));
            }
            // 销量
            if(searchMap.get("saleNum")!=null ){
                criteria.andEqualTo("saleNum",searchMap.get("saleNum"));
            }
            // 评论数
            if(searchMap.get("commentNum")!=null ){
                criteria.andEqualTo("commentNum",searchMap.get("commentNum"));
            }

        }
        return example;
    }

}
